package com.prawn.authority.controller;

import com.prawn.authority.service.EmailService;
import com.prawn.authority.utils.IpAddressUtil;
import entity.Result;
import entity.StatusCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Api(value = "邮箱Controller", tags = "发送邮件验证码模块")
@RestController
@CrossOrigin
@RequestMapping("/email")
public class EmailController {

    @Value("${mail.ttl}")
    private int ttl;

    @Value("${mail.times}")
    private int times;

    @Autowired
    private EmailService emailService;

    @Autowired
    private RedisTemplate redisTemplate;

    @ApiOperation(value = "获取邮箱验证码")
    @RequestMapping(value = "/{addr:.+}", method = RequestMethod.GET)
    @ResponseBody
    public Result getCheckCode(@PathVariable String addr, HttpServletRequest request) {
        String ipAddr = IpAddressUtil.getIpAdrress(request);
        // 获取redis中记录的同一个邮箱发送的次数
        Object addrNum = redisTemplate.opsForValue().get(addr + "_num");
        // 获取redis中记录的同一个ip发送的次数
        Object ipAddrNum = redisTemplate.opsForValue().get(ipAddr + "_num");

        // 第一次发送邮件，redis没有存邮箱次数和ip次数
        if (addrNum == null && ipAddrNum == null) {
            redisTemplate.opsForValue().set(addr + "_num", 1, ttl, TimeUnit.MINUTES);
            redisTemplate.opsForValue().set(ipAddr + "_num", 1, ttl, TimeUnit.MINUTES);
        } else {
            // 有可能在同一个ip下向两个邮箱发送，或者同一个邮箱在两个ip发送
            // 这时第二个邮箱或ip在redis中获取的num为null
            // 需判断是否为空
            int addrNumInt = addrNum == null ? 1 : (int) addrNum;
            int ipAddrNumInt = ipAddrNum == null ? 1 : (int) ipAddrNum;

            redisTemplate.opsForValue().set(addr + "_num", addrNumInt + 1, ttl, TimeUnit.MINUTES);
            redisTemplate.opsForValue().set(ipAddr + "_num", ipAddrNumInt + 1, ttl, TimeUnit.MINUTES);

            // 次数超过限制
            if (addrNumInt > times || ipAddrNumInt > times) {
                return new Result(false, StatusCode.ERROR, "请求次数过于频繁，请" + ttl + "分钟后重试");
            }
        }

        if (!StringUtils.isEmpty(addr)) {
            String checkCode = String.valueOf(new Random().nextInt(899999) + 100000);
            try {
                emailService.sendMail(addr, "注册验证码", checkCode);
            } catch (Exception e) {
                e.printStackTrace();
                return new Result(false, StatusCode.ERROR, "验证码发送失败");
            }
            return new Result(true, StatusCode.OK, "验证码发送成功");
        }
        return null;
    }

    /**
     * 检查邮箱是否已注册
     *
     * @param addr
     * @return
     */
    @ApiOperation("检查邮箱是否已注册")
    @RequestMapping(value = "/checkEmail/{addr:.+}", method = RequestMethod.GET)
    public Result checkEmail(@PathVariable String addr) {
        if (!emailService.checkEmailRegisted(addr)) {
            return new Result(false, StatusCode.ERROR, "该邮箱已注册");
        }
        return new Result(true, StatusCode.OK, "该邮箱未注册");
    }
}